package com.mz.mattress.core.voice;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class VoiceControlPacket2 {

    // 固定包头
    public static final byte[] HEADER = {(byte) 0xAA, (byte) 0x55};
    // 固定结束符
    public static final byte END_MARKER = (byte) 0xAF;
    // 默认设备地址
    public static final byte DEFAULT_ADDRESS = 0x64;

    private byte sequence;      // 流水号
    private byte address;       // 设备地址
    private byte reserved;      // 保留字段
    private byte command;       // 命令值
    private byte[] data;        // 数据内容
    private byte[] crc;         // CRC16校验码

    public VoiceControlPacket2(byte sequence, byte command, byte[] data) {
        this(sequence, DEFAULT_ADDRESS, command, data);
    }

    public VoiceControlPacket2(byte sequence, byte address, byte command, byte[] data) {
        this.sequence = sequence;
        this.address = address;
        this.reserved = 0x00;
        this.command = command;
        this.data = data != null ? data : new byte[0];
        calculateCRC();
    }

    /**
     * 计算CRC16校验码
     */
    private void calculateCRC() {
        // CRC计算范围：从流水号到数据结束
        byte[] crcData = toByteArrayWithoutCRC();
//        this.crc = CRC16.calculateCRC16(crcData, 1, crcData.length - 1);
    }

    /**
     * 将数据包转换为字节数组（不包含CRC和结束符）
     */
    private byte[] toByteArrayWithoutCRC() {
        int dataLength = data.length;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        try {
            // 包头
            baos.write(HEADER);
            // 流水号
            baos.write(sequence);
            // 地址
            baos.write(address);
            // 保留
            baos.write(reserved);
            // 命令
            baos.write(command);
            // 长度（高字节在前）
            baos.write((byte) ((dataLength >> 8) & 0xFF));
            baos.write((byte) (dataLength & 0xFF));
            // 数据
            if (dataLength > 0) {
                baos.write(data);
            }
        } catch (IOException e) {
            // 不会发生，因为ByteArrayOutputStream不会抛出IOException
        }

        return baos.toByteArray();
    }

    /**
     * 将完整数据包转换为字节数组
     */
    public byte[] toByteArray() {
        byte[] baseData = toByteArrayWithoutCRC();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        try {
            baos.write(baseData);
            // CRC校验码
            baos.write(crc);
            // 结束符
            baos.write(END_MARKER);
        } catch (IOException e) {
            // 不会发生
        }

        return baos.toByteArray();
    }

    /**
     * 从字节数组解析数据包
     */
    public static VoiceControlPacket2 fromByteArray(byte[] packetData) throws IllegalArgumentException {
        if (packetData == null || packetData.length < 12) {
            throw new IllegalArgumentException("数据包长度不足");
        }

        // 检查包头
        if (packetData[0] != HEADER[0] || packetData[1] != HEADER[1]) {
            throw new IllegalArgumentException("无效的包头");
        }

        // 检查结束符
        if (packetData[packetData.length - 1] != END_MARKER) {
            throw new IllegalArgumentException("无效的结束符");
        }

        int pos = 2; // 跳过包头

        byte sequence = packetData[pos++];
        byte address = packetData[pos++];
        byte reserved = packetData[pos++];
        byte command = packetData[pos++];

        // 读取长度（高字节在前）
        int length = ((packetData[pos] & 0xFF) << 8) | (packetData[pos + 1] & 0xFF);
        pos += 2;

        // 检查数据长度
        if (packetData.length != pos + length + 3) { // +3 表示CRC(2) + 结束符(1)
            throw new IllegalArgumentException("数据长度不匹配");
        }

        // 读取数据
        byte[] data = new byte[length];
        if (length > 0) {
            System.arraycopy(packetData, pos, data, 0, length);
            pos += length;
        }

        // 读取CRC
        byte[] crc = new byte[2];
        crc[0] = packetData[pos++];
        crc[1] = packetData[pos];

        // 验证CRC
        byte[] crcData = new byte[packetData.length - 5]; // 从流水号到数据结束
        System.arraycopy(packetData, 2, crcData, 0, crcData.length);

//        if (!CRC16.verifyCRC16(crcData, 0, crcData.length, crc)) {
//            throw new IllegalArgumentException("CRC校验失败");
//        }

        VoiceControlPacket2 packet = new VoiceControlPacket2(sequence, address, command, data);
        packet.reserved = reserved;
        packet.crc = crc;

        return packet;
    }

    // Getter 方法
    public byte getSequence() { return sequence; }
    public byte getAddress() { return address; }
    public byte getCommand() { return command; }
    public byte[] getData() { return data; }
    public byte[] getCrc() { return crc; }

    @Override
    public String toString() {
        return String.format("VoiceControlPacket{seq=0x%02X, addr=0x%02X, cmd=0x%02X, dataLen=%d}",
                sequence & 0xFF, address & 0xFF, command & 0xFF, data.length);
    }
}